/*
 * Copyright 2009-2010 Nanjing RedOrange ltd (http://www.red-orange.cn)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package redora.client.ui;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.SimplePanel;
import redora.client.Persistable;
import redora.client.mvp.ClientFactory;
import redora.client.mvp.FetchEvent;

import java.util.logging.Logger;

import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO;
import static redora.client.Persistable.Scope.List;

/**
 * Anchor style widget that allows lazy retrieval of typically a n-to-1 relationship.
 * When the related pojo is not in the cache, it will show a 'see details' anchor.
 * When clicked by the user, it will be fetched from the server.<br>
 * The widget uses the cache service and has a listeners on it's pojo. When
 * the pojo is updated elsewhere, the change will synced. This also implies that as
 * soon as somewhere the pojo is fetched, this widget will be updated.
 * @author Nanjing Redorange (www.red-orange.cn)
 */
public class LazyAnchor extends Composite {
    static Logger l = Logger.getLogger("LazyAnchor");

    static RedoraResource redoraResource = GWT.create(RedoraResource.class);

    final Class<? extends Persistable> cls;
    final Long fetchId;
    final ClientFactory clientFactory;
    final SimplePanel panel;

    public LazyAnchor(final Class<? extends Persistable> cls, final Long fetchId, final ClientFactory clientFactory) {
        this.cls = cls;
        this.fetchId = fetchId;
        this.clientFactory = clientFactory;
        panel = new SimplePanel();
        if (fetchId == null)
            l.log(FINE, "Ignoring empty anchor");
        else if (clientFactory.getLocator().locateService(cls).useCache(fetchId, List)) {
            Label label = new Label(clientFactory.getLocator().locateService(cls).cache(fetchId).toListString());
            label.setStyleName(redoraResource.css().redoraLazyAnchor());
            panel.setWidget(label);
        } else {
            Anchor label = new Anchor("see details");
            label.addClickHandler(new ClickHandler() {
                public void onClick(ClickEvent event) {
                    panel.clear();
                    panel.setWidget(new Image("images/loading.gif"));
                    clientFactory.getLocator().locateService(cls).findById(fetchId, List);
                }
            });
            panel.setWidget(label);
        }
        this.initWidget(panel);
        if (fetchId != null)
            bind();
    }

    private void bind() {
        clientFactory.getEventBus().addHandler(FetchEvent.TYPE,
                new FetchEvent.Handler() {
                    @Override
                    public void onSuccess(FetchEvent event) {
                        if (event.hasMe(cls, fetchId)) {
                            l.log(INFO, "Processing FetchEvent for LazyAnchor widget: " + event.getPojo(fetchId));
                            panel.clear();
                            Label label = new Label(event.getPojo(fetchId).toListString());
                            label.setStyleName(redoraResource.css().redoraLazyAnchor());
                            panel.setWidget(label);
                        }
                    }
                });
    }
}